﻿using DTM.Core.Exceptions;
using DTM.Model;
using DTM.Repository;
using FluentValidation;
using FluentValidation.Results;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;

namespace DTM.Domain.Players.Tests.Units
{
    [TestClass()]
    public class PlayerServiceTests
    {
        #region Fields

        private IUnitOfWorkProvider _provider;
        private PlayerService _service;
        private IValidator<IPlayer> _validator;

        #endregion Fields

        #region Methods

        [TestInitialize]
        public void Initialize()
        {
            _provider = Substitute.For<IUnitOfWorkProvider>();
            _validator = Substitute.For<IValidator<IPlayer>>();

            _service = new PlayerService(_provider, _validator);
        }

        [TestMethod()]
        [ExpectedException(typeof(CustomValidationException))]
        public void Update_PlayerIsNotValid_ThrowsException()
        {
            var player = Substitute.For<IPlayer>();
            _validator.Validate(player).Returns(new ValidationResult(new ValidationFailure[] { new ValidationFailure("name", "error") }));

            _service.Update(player);
        }

        [TestMethod()]
        public void Update_PlayerIsValid_UpdateIdDone()
        {
            var player = Substitute.For<IPlayer>();
            var unitOfWork = Substitute.For<IUnitOfWork>();
            var repository = Substitute.For<IPlayerRepository>();
            unitOfWork.Players.Returns(repository);
            _provider.GetUnitOfWork().Returns(unitOfWork);
            _validator.Validate(player).Returns(new ValidationResult());

            _service.Update(player);

            repository.ReceivedWithAnyArgs(1).Update(null);
        }

        [TestMethod()]
        [ExpectedException(typeof(CustomValidationException))]
        public void Insert_PlayerIsNotValid_ThrowsException()
        {
            var player = Substitute.For<IPlayer>();
            _validator.Validate(player).Returns(new ValidationResult(new ValidationFailure[] { new ValidationFailure("name", "error") }));

            _service.Insert(player);
        }

        [TestMethod()]
        public void Insert_PlayerIsValid_UpdateIdDone()
        {
            var player = Substitute.For<IPlayer>();
            var unitOfWork = Substitute.For<IUnitOfWork>();
            var repository = Substitute.For<IPlayerRepository>();
            unitOfWork.Players.Returns(repository);
            _provider.GetUnitOfWork().Returns(unitOfWork);
            _validator.Validate(player).Returns(new ValidationResult());

            _service.Insert(player);

            repository.ReceivedWithAnyArgs(1).Insert(null);
        }

        #endregion Methods
    }
}